import {
  AxiosHeaders,
  AxiosInstance,
  AxiosPromise,
  InternalAxiosRequestConfig,
  Method,
  RawAxiosRequestHeaders,
} from 'axios'
import {Interceptors} from './request' // 引入自定义的axios拦截器模块

// 定义一个 不确定是什么类型 但一定是个数组的 类型
type NestedArray = number[] | string[] | object[] | NestedArray[]

/**
 * 定义请求配置类型，用于描述发起HTTP请求所需的各种配置项。
 */
interface RequestConfigType {
  url?: string // 请求的URL
  method?: Method | string // 请求方法，如'GET'、'POST'等
  headers?: RawAxiosRequestHeaders | AxiosHeaders // 请求头信息
  params?: object | NestedArray // 请求的查询参数对象或数组
  data?: object | NestedArray // 请求体数据对象或数组
  duplicateRequestValidation?: boolean // 是否启用重复请求验证，默认应为true
  duplicateRequestValidationTime?: number // 重复请求的时间间隔限制
}

/**
 * HttpServer类，用于封装axios实例并提供简化版的HTTP请求方法。
 */
export class HttpServer {
  axios: AxiosInstance // 存储axios实例

  /**
   * 构造函数，初始化axios实例，并通过拦截器模块获取配置好的axios实例。
   */
  constructor() {
    this.axios = new Interceptors().getInterceptors()
  }

  /**
   * 内部方法，为传入的请求配置添加默认值，主要是设置'duplicateRequestValidation'为true。
   * @param config 请求的原始配置对象
   * @returns 带有默认配置的请求配置对象
   */
  private requestWithDefaults(
    config: RequestConfigType
  ): InternalAxiosRequestConfig {
    const defaultConfig: RequestConfigType = {
      duplicateRequestValidation: true, // 设置默认值
    }
    return {...defaultConfig, ...config} as InternalAxiosRequestConfig
  }

  /**
   * 通用请求方法，处理所有类型的HTTP请求。
   * @param config 请求配置对象，会应用默认配置
   * @returns AxiosPromise，表示异步请求的Promise
   */
  request<T = any>(config: RequestConfigType): AxiosPromise<T> {
    return this.axios.request<T>(this.requestWithDefaults(config))
  }

  // 以下为简化版的HTTP方法，直接调用request方法并设定method
  post<T = any>(config: RequestConfigType): AxiosPromise<T> {
    return this.request<T>({...config, method: 'post'})
  }

  get<T = any>(config: RequestConfigType): AxiosPromise<T> {
    return this.request<T>({...config, method: 'get'})
  }

  delete<T = any>(config: RequestConfigType): AxiosPromise<T> {
    return this.request<T>({...config, method: 'delete'})
  }

  put<T = any>(config: RequestConfigType): AxiosPromise<T> {
    return this.request<T>({...config, method: 'put'})
  }

  patch<T = any>(config: RequestConfigType): AxiosPromise<T> {
    return this.request<T>({...config, method: 'patch'})
  }
}

// 实例化HttpServer并导出，便于其他模块使用
const http = new HttpServer()
export default http
